package com.zzm.validate.web.injector;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import com.zzm.validate.web.FormValidatorStub;

public class ArgInjectorFactory {

	private static final String classPathConfig = "validate-injectors.properties";
	
	private Map<String, ArgInjector> argInjectors;
	
	private FormValidatorStub formValidatorStub;
	
	public ArgInjectorFactory() {
		argInjectors = new HashMap<String, ArgInjector>();
		registerArgInjectors();
		loadClassPathConfig();
	}

	@SuppressWarnings("rawtypes")
	private void loadClassPathConfig() {
		Properties pro = new Properties();
		try {
			InputStream is = this.getClass().getClassLoader().getResourceAsStream(classPathConfig);
			pro.load(is);
		} catch (Exception e) {
			return;
		}
		for(Entry entry : pro.entrySet()) {
			String key = entry.getKey().toString();
			String value = entry.getValue().toString();
			ArgInjector injector = this.createInjectorByName(value, key);
			this.argInjectors.put(injector.getInjectKey(), injector);
		}
	}
	
	private ArgInjector createInjectorByName(String className, String key) {
		try {
			ArgInjector injector =  (ArgInjector) Class.forName(className).getDeclaredConstructor(String.class).newInstance(key);
			return injector;
		} catch(Exception e) {
			throw new InjectorException("Fail to create class:" + className + " key=" + key);
		}
	}

	private void registerArgInjectors() {
		ArgInjector injector1 = new ResourceArgInjector();
		this.argInjectors.put(injector1.getInjectKey(), injector1);
		ArgInjector injector2 = new FieldValueInjector();
		this.argInjectors.put(injector2.getInjectKey(), injector2);
		ArgInjector injector3 = new VarValueInjector();
		this.argInjectors.put(injector3.getInjectKey(), injector3);
		ArgInjector injector4 = new BundleArgInjector();
		this.argInjectors.put(injector4.getInjectKey(), injector4);
	}
	
	public void registerUserArgInjector(ArgInjector argInjector) {
		this.argInjectors.put(argInjector.getInjectKey(), argInjector);
	}
	
	public ArgInjector getArgInjector(String key) {
		return this.argInjectors.get(key);
	}
	
	public FormValidatorStub getFormValidatorStub() {
		return formValidatorStub;
	}

	public void setFormValidatorStub(FormValidatorStub formValidatorStub) {
		this.formValidatorStub = formValidatorStub;
		for(Entry<String, ArgInjector> entry : argInjectors.entrySet()) {
			entry.getValue().setFormValidatorStub(formValidatorStub);
		}
	}
}
